﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using machine_tool;
using artist;
using System.Threading;

namespace stanok
{

 struct Position
{
    public int x;
    public int y;
    public int z;
}

//Описание точки в пространстве
//
//  0 - пусто
//  1 - деталь
//  2 - резец
 enum cntrl { STOP = 0, FORWARD = 1, BACKWARD = 2, RIGHT = 4, LEFT = 3, UP = 6, DOWN = 5 };
 struct Data3D
 {
    public int x;
    public int y;
    public int z;
    public int type;
 }
//Описание 3D модели
struct Model3D
 {
    public int length;
    public int width;
    public int height;
    public ArrayList points;
 }

    class World
    {
        //Класс для отрисовки
        public Artist artist;
        //Класс станок
        public MachineTool machine; 
        //Длина пропила
        private int modelWidth = 3;
        private int modelHeight = 3;
        private int modelLength = 3;
        //Панели для отображения иекущей координаты резца
        private Label labelx;
        private Label labely;
        private Label labelz;




        private int cuttingLength = 0;
        //Ширина пропила
        private int cuttingWidth = 0;
        //Высота пропила
        private int cuttingHeight = 0;
        //Текущая позиция резца
        private Position currentPosition; 
        //Атоматический режим
        private Boolean autoMode = false;
        //3D модель объекта
        private Model3D model;
        //Панели для прорисовки вида сверху
        private Panel panelUp;
        //Панели для прорисовки вида сбоку
        private Panel panelDown;
        //Listbox для текстовых сообщений
        private ListBox listText;
        
        public World( int length, int width, int height, Position p, Boolean mode, Panel pan1, Panel pan2, Label lx, Label ly, Label lz, ListBox lb  )
        {
            cuttingHeight = height;
            cuttingWidth = width;
            cuttingLength = length;
            currentPosition = p;
            autoMode = mode;
            panelUp = pan1;
            panelDown = pan2;

            labelx = lx;
            labely = ly;
            labelz = lz;
            listText = lb;

            //Инициализа вторичных классов            
            machine = new MachineTool( 2, 2, 3);
            artist = new Artist(panelUp, panelDown);            
            createModel();
            artist.dravTest(model);
            
        }
        //Запуск выпиливания
        public void strart()
        {
            Boolean enable = true;
            //Обработка команды от станка
            while ( enable )
            {
                int comand = 0;
                comand = machine.cutChannel();
                if (comand == 0)
                    break;
                changeModel(comand);
                showPosition();
                artist.dravTest(model);
                //artist.dravTest(model,comand);
                Thread.Sleep(500);
               //artist.draw(model, comand);
                //artist.draw(model, 1);
                

            }
            listText.Items.Add("Готово");
        }

        public void nextStep()
        {
            int comand = 0;
            comand = machine.cutChannel();
            if (comand == 0)
            {
                listText.Items.Add("Готово");

            }
            else
            {
                changeModel(comand);
                showPosition();
            }
            

        }

        private int changeModel(int comond)
        {
            Data3D mb;

            int rezecPosition = 0;
            //Ищим положение резца
            for (int i = 0; i < modelWidth * modelLength * modelHeight; i++)
            {
                mb =(Data3D) model.points[i];
                if(mb.type == 2)
                    rezecPosition = i;
                }
            //Проверяем адекватность команды и выполняем её
            mb = (Data3D) model.points[rezecPosition];
            //Команда сдвинутся вперёд
            if (comond == 1)
            {
                if (mb.y >= modelLength)
                    return 0;
                else
                {
                    setRezrc(mb.x, mb.y + 1, mb.z, 2);
                    setRezrc(mb.x, mb.y, mb.z, 0);
                } 
            }
            //Команда сдвинутся назад
            if (comond == 2)
            {
                if (mb.y <= 0)
                    return 0;
                else
                {
                    setRezrc(mb.x, mb.y - 1, mb.z, 2);
                    setRezrc(mb.x, mb.y, mb.z, 0);
                }
            }
            //Команда сдвинутся вправо
            if (comond == 3)
            {
                if (mb.x >= modelWidth)
                    return 0;
                else
                {
                    setRezrc(mb.x + 1, mb.y, mb.z, 2);
                    setRezrc(mb.x, mb.y, mb.z, 0);
                    
                }
            }
            //Команда сдвинутся влево
            if (comond == 3)
            {
                if (mb.x <= 0)
                    return 0;
                else
                {
                    setRezrc(mb.x - 1, mb.y, mb.z, 2);
                    setRezrc(mb.x, mb.y, mb.z, 0);
                }
            }



            //Команда сдвинутся вверх
            if (comond == 4)
            {
                if (mb.z >= modelHeight)
                    return 0;
                else
                {
                    setRezrc(mb.x + 1, mb.y, mb.z, 2);
                    setRezrc(mb.x, mb.y, mb.z, 0);
                    
                }
            }
            //Команда сдвинутся вниз
            if (comond == 5)
            {
                if (mb.z <= 0)
                    return 0;
                else
                {
                    setRezrc(mb.x , mb.y, mb.z - 1, 2);
                    setRezrc(mb.x, mb.y, mb.z, 0);
                }
            }
            return 0;
        }

        private void setRezrc(int x, int y, int z,int mode)
        {
            Data3D mb = new Data3D();
            for (int i = 0; i < modelWidth * modelLength * modelHeight; i++)
            {
                mb = (Data3D) model.points[i];
                if ((mb.x == x) && (mb.y == y) && (mb.z == z))
                {
                    model.points.RemoveAt(i);
                    mb.type = mode;
                    model.points.Insert(i,mb);

                }
            }
        }
        // Создания пустой модели 
        private void createModel()
        {
            model = new Model3D();
            model.points = new ArrayList();
            Data3D mb = new Data3D();
            for(int x = 0; x < modelWidth; x++)
                for(int y = 0; y < modelLength; y++)
                    for(int z = 0; z < modelHeight; z++){
                        mb.x = x;
                        mb.y = y;
                        mb.z = z;
                        if(y == 0)
                            mb.type = 1;
                        else
                            mb.type = 0;
                        model.points.Add(mb);
            }
            model.points.RemoveAt(2);            
            mb.x = 0;
            mb.y = 0;
            mb.z = 2;
            mb.type = 2;
            model.points.Insert(0, mb);

            model.width = modelWidth;
            model.height = modelHeight;
            model.length = modelLength;
        }
        //Выводим положение резца
        private void showPosition()
        {
            Data3D mb = new Data3D();
            int count = model.length * model.width * model.height;
            for (int i = 0; i < count; i++)
            {
                mb = (Data3D) model.points[i];
                if(mb.type == 2)
                {
                    labelx.Text = mb.x.ToString();
                    labelx.Update();
                    labely.Text = mb.y.ToString();
                    labely.Update();
                    labelz.Text = mb.z.ToString();
                    labelz.Update();
                }
            }
        }    
    }
}
